import { _decorator, Animation, Camera, Color, Component, director, EditBox, Event, EventMouse, EventTouch, ImageAsset, Label, Layers, math, native, Node, RenderTexture, Sprite, SpriteFrame, sys, SystemEvent, Texture2D, UITransform, Vec3 } from 'cc';
import { GLOBALUtil } from './GlobalUtil';
import { MenuSceneManager } from './MenuSceneManager';
import { GLOBALVar } from './GlobalVar';
const { ccclass, property } = _decorator;

@ccclass('ModifyPersonalDataManager')
export class ModifyPersonalDataManager extends Component {
    @property({type: Node, tooltip: "MenuSenceManager"})
    private MenuSenceManager: Node = null;
    @property({type: Node, tooltip: "昵称"})
    private Nickname: Node = null;
    @property({type: Node, tooltip: "头像"})
    private Avatar: Node = null;
    @property({type: Node, tooltip: "编辑按钮"})
    private BtnNickname: Node = null;
    @property({type: Node, tooltip: "修改名字面板"})
    private ModifyNameNode: Node = null;
    @property({type: Node, tooltip: "上传头像面板"})
    private ModifyAvatarNode: Node = null;
    @property({type: Node, tooltip: "昵称编辑框"})
    private ModifyNameEditBox: Node = null;
    @property({type: Node, tooltip: "新头像"})
    private newAvatar: Node = null;
    @property({type: Node, tooltip: "裁切框"})
    private CutCircle: Node = null;
    @property({type: Node, tooltip: "AvatarMask"})
    private AvatarMask: Node = null;
    
    private touchStartPos: Vec3 = new Vec3();
    private avatarStartPos: Vec3 = new Vec3();
    private isDragging: boolean = false;

    //缩放相关
    private initialDistance: number = 0; // 初始双指距离
    private initialScale: number = 1; // 初始缩放值
    private minScale: number = 0.2; // 最小缩放值
    private maxScale: number = 3; // 最大缩放值

    protected onEnable(): void {

    }
    start() {
        this.updateUI();
    }

    update(deltaTime: number) {
        
    }

    openModifyNameNode() {
        this.ModifyNameNode.active = true;
        this.ModifyNameNode.getChildByName("img_bg").getComponent(Animation).play("ScaleAnime_0.8_1");
    }
    openModifyAvatarNode() {
        this.ModifyAvatarNode.active = true;
        this.ModifyAvatarNode.getChildByName("img_bg").getComponent(Animation).play("ScaleAnime_0.8_1");
        // 重置头像位置到中心a
        this.newAvatar.setPosition(Vec3.ZERO);
        
        // 绑定事件
        this.AvatarMask.on(Node.EventType.TOUCH_START, this.onTouchStart, this);
        this.AvatarMask.on(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
        this.AvatarMask.on(Node.EventType.TOUCH_END, this.onTouchEnd, this);
        this.AvatarMask.on(Node.EventType.TOUCH_CANCEL, this.onTouchEnd, this);
        this.ModifyAvatarNode.on(Node.EventType.MOUSE_WHEEL, this.onMouseWheel, this);
    }

    //打开资源管理器选择图片
    onClickAvatar() {
        if (sys.isBrowser) {
            GLOBALUtil.handleImageSelect((imageAsset: ImageAsset) => {
                //选择结束后
                this.openModifyAvatarNode();
                const texture2d = new Texture2D();
                texture2d.image = imageAsset;
                const spriteFrame = new SpriteFrame();
                spriteFrame.texture = texture2d;
                this.newAvatar.getComponent(Sprite).spriteFrame = spriteFrame;
            })
        } else if (sys.isNative && sys.os === sys.OS.ANDROID) {
            GLOBALUtil.handleImageSelect((imageAsset: ImageAsset) => {
            })
        }
        
    }

    async onClickFinish(event: Event) {
        const EventNode: Node = event.target as unknown as Node;
        //把图片裁切
        const imgData = await this.cropImageToBlob();
        //上传到服务器
        try {
            if (sys.isBrowser) {
                const response = await GLOBALUtil.uploadAvatar(imgData as Blob);
                GLOBALUtil.LoadMessage(true, response.msg, this.node,new Vec3(50, 950, 0), true, 1);
                this.closeModifyAvatar();
                this.updateUI();
            } else if (sys.isNative && sys.os === sys.OS.ANDROID) {
                const response = await GLOBALUtil.uploadAvatarByAndroid(imgData as Uint8Array);
                GLOBALUtil.LoadMessage(true, response.msg, this.node,new Vec3(50, 950, 0), true, 1);
                this.closeModifyAvatar();
                this.updateUI();
            }
        } catch (error) {
            console.error(error)
            return;
        }
    }

    async uploadNickname(event: Event) {
        const EventNode: Node = event.target as unknown as Node;
        const nickname = this.ModifyNameEditBox.getComponent(EditBox).string;
        if (GLOBALUtil.isBlankString(nickname)) {
            console.log("昵称不能为空！")
            GLOBALUtil.LoadMessage(true, "昵称不能为空！", EventNode.parent,new Vec3(50, 950, 0), true, 2);
            return;
        }
        const nameLength = GLOBALUtil.calculateStringLength(nickname);
        if (nameLength > 18) {
            GLOBALUtil.LoadMessage(true, "昵称不能超过18个字符！", EventNode.parent,new Vec3(50, 950, 0), true, 2);
            return;
        }
        // 上传昵称
        try {
            const res = await GLOBALUtil.uploadNickname(nickname);
            GLOBALUtil.LoadMessage(true, "修改昵称成功！", this.node,new Vec3(50, 950, 0), true, 1);
            // 更新显示
            this.closeModifyName();
            this.updateUI();
        } catch (error) {
            console.error(error)
            GLOBALUtil.LoadMessage(true, "修改昵称失败！", EventNode.parent,new Vec3(50, 950, 0), true, 0);
        }
    }

    closeModifyName() {
        const Anime = this.ModifyNameNode.getChildByName("img_bg").getComponent(Animation);
        Anime.play("ScaleAnime_1_0.8");
        Anime.once(Animation.EventType.FINISHED, () => {
            this.ModifyNameNode.active = false;
        }); 
    }
    closeModifyAvatar() {
        //解绑鼠标滚轮事件
        this.ModifyAvatarNode.off(Node.EventType.MOUSE_WHEEL, this.onMouseWheel, this);
        const Anime = this.ModifyAvatarNode.getChildByName("img_bg").getComponent(Animation);
        Anime.play("ScaleAnime_1_0.8");
        Anime.once(Animation.EventType.FINISHED, () => {
            this.ModifyAvatarNode.active = false;
        });
    }

    async updateUI() {
        type UserInfo = {
            nickname: string,
            avatar_url: string,
            userID: string
        }
        try {
            // 获取数据库的信息更新界面
            const data: UserInfo = await GLOBALUtil.getUserInfo() as UserInfo;
            // 更新昵称
            GLOBALVar.avatarUrlCache = data.avatar_url;
            GLOBALVar.nicknameCache = data.nickname;
            this.Nickname.getComponent(Label).string = data.nickname;
            this.scheduleOnce(() => {
                const width = this.Nickname.getComponent(UITransform).width;
                this.BtnNickname.setPosition(new Vec3(width + 5, 0, 0));
            }, 0);            
            // 更新头像
            GLOBALUtil.loadNetImage(data.avatar_url, (sp) => {
                this.Avatar.getComponent(Sprite).spriteFrame = sp;
                GLOBALVar.avatarSpriteCache = sp;
                //更新主菜单页面的头像和昵称
                if (this.MenuSenceManager) {
                    const menuSceneManager = this.MenuSenceManager.getComponent("MenuSceneManager") as MenuSceneManager;
                    if (menuSceneManager) {
                        menuSceneManager.updateUI();
                    }
                }  
            })


        } catch (error) {
            console.error(error)
        }
    }

    onTouchStart(event: EventTouch) {
        const touches = event.getTouches();
        if (touches.length === 2) {
            // 记录双指的起始位置和初始距离
            const touch1 = touches[0].getLocation();
            const touch2 = touches[1].getLocation();
            this.touchStartPos.set((touch1.x + touch2.x) / 2, (touch1.y + touch2.y) / 2);
            this.initialDistance = Math.sqrt(Math.pow(touch1.x - touch2.x, 2) + Math.pow(touch1.y - touch2.y, 2));
        } else if (touches.length === 1) {
            // 单指拖动逻辑
            this.isDragging = true;
            const touch = touches[0];
            const touchPos = touch.getLocation();
            const localPos = this.AvatarMask.getComponent(UITransform)!.convertToNodeSpaceAR(new Vec3(touchPos.x, touchPos.y));
            this.touchStartPos.set(localPos);
            this.avatarStartPos.set(this.newAvatar.position);
        }
    }
    
    onTouchMove(event: EventTouch) {
        const touches = event.getTouches();
    if (touches.length === 2) {
        const touch1 = touches[0].getLocation();
        const touch2 = touches[1].getLocation();
        const currentDistance = Math.sqrt(Math.pow(touch1.x - touch2.x, 2) + Math.pow(touch1.y - touch2.y, 2));

        // 计算缩放比例
        const scaleFactor = currentDistance / this.initialDistance;

        // 引入速度控制因子
        const speedFactor = 3; // 值越小，缩放速度越慢；值越大，缩放速度越快
        const adjustedScaleFactor = 1 + (scaleFactor - 1) * speedFactor;

        // 计算目标缩放值
        let targetScale = this.newAvatar.scale.x * adjustedScaleFactor;

        // 限制目标缩放范围
        targetScale = math.clamp(targetScale, this.minScale, this.maxScale);

        // 使用 math.lerp 实现平滑缩放
        const currentScale = this.newAvatar.scale.x;
        const smoothFactor = 0.5; // 平滑系数，值越小越平滑
        const smoothedScale = math.lerp(currentScale, targetScale, smoothFactor);

        // 应用缩放
        this.newAvatar.setScale(new Vec3(smoothedScale, smoothedScale, 1));

        // 更新初始距离
        this.initialDistance = currentDistance;
        } else if (touches.length === 1 && this.isDragging) {
            // 单指拖动逻辑
            const touch = touches[0];
            const currentTouchPos = touch.getLocation();
            const currentLocalPos = this.AvatarMask.getComponent(UITransform)!.convertToNodeSpaceAR(new Vec3(currentTouchPos.x, currentTouchPos.y));
            const delta = new Vec3(
                currentLocalPos.x - this.touchStartPos.x,
                currentLocalPos.y - this.touchStartPos.y,
                0
            );
            const newPos = new Vec3(
                this.avatarStartPos.x + delta.x,
                this.avatarStartPos.y + delta.y,
                0
            );
            const avatarTrans = this.newAvatar.getComponent(UITransform)!;
            const maskTrans = this.CutCircle.getComponent(UITransform)!;
            const maxX = (avatarTrans.width * this.newAvatar.scale.x - maskTrans.width) / 2;
            const maxY = (avatarTrans.height * this.newAvatar.scale.y - maskTrans.height) / 2;
            newPos.x = math.clamp(newPos.x, -maxX, maxX);
            newPos.y = math.clamp(newPos.y, -maxY, maxY);
            this.newAvatar.setPosition(newPos);
        }
    }
    
    onTouchEnd(event: EventTouch) {
        this.isDragging = false;
        const touches = event.getTouches();
        if (touches.length === 2) {
            // 重置双指起始位置和初始距离
            this.touchStartPos.set(Vec3.ZERO);
            this.initialDistance = 0;
        }
    }

    // 鼠标滚轮缩放的逻辑
    onMouseWheel(event: EventMouse) {
    const delta = event.getScrollY(); // 获取滚轮滚动值
    const scaleSpeed = 0.1; // 缩放速度
    let newScale = this.newAvatar.scale.x + (delta > 0 ? scaleSpeed : -scaleSpeed);
    // 限制缩放范围
    newScale = math.clamp(newScale, this.minScale, this.maxScale);
    this.newAvatar.setScale(new Vec3(newScale, newScale, 1));
    }

    private cropImageToBlob(): Promise<Blob | Uint8Array> {
        return new Promise<Blob | Uint8Array>((resolve, reject) => {
            const cutCircleTransform = this.CutCircle.getComponent(UITransform);
            const width = cutCircleTransform.width;
            const height = cutCircleTransform.height;
    
            const cameraNode = new Node('CaptureCamera');
            this.CutCircle.addChild(cameraNode);
            const camera = cameraNode.addComponent(Camera);
    
            camera.projection = Camera.ProjectionType.ORTHO;
            camera.orthoHeight = height / 2;
            camera.near = 0.1;
            camera.far = 1000;
            camera.clearColor = new Color(0, 0, 0, 0);
            camera.visibility = Layers.Enum.UI_2D;
    
            const renderTexture = new RenderTexture();
            renderTexture.reset({
                width: width,
                height: height,
            });
            camera.targetTexture = renderTexture;
    
            cameraNode.setPosition(0, 0, 500);
    
            director.root.frameMove(0);
    
            const pixels = renderTexture.readPixels();
            if (!pixels) {
                reject(new Error("Failed to read render texture pixels"));
                return;
            }

            if (sys.os === sys.OS.ANDROID) {
                //直接把Uint8Array数据发送到服务器
                resolve(pixels)
            } else if (sys.isBrowser) {
                // Web的逻辑
                const tempCanvas = document.createElement('canvas');
                tempCanvas.width = width;
                tempCanvas.height = height;
                const tempCtx = tempCanvas.getContext('2d');
                if (!tempCtx) {
                    reject(new Error("Failed to create canvas context"));
                    return;
                }
        
                const imageData = new ImageData(new Uint8ClampedArray(pixels), width, height);

                const flippedImageData = new ImageData(width, height);
                for (let y = 0; y < height; y++) {
                    for (let x = 0; x < width; x++) {
                        const srcIndex = (y * width + x) * 4;
                        const dstIndex = ((height - 1 - y) * width + x) * 4;
                        flippedImageData.data[dstIndex] = imageData.data[srcIndex];
                        flippedImageData.data[dstIndex + 1] = imageData.data[srcIndex + 1];
                        flippedImageData.data[dstIndex + 2] = imageData.data[srcIndex + 2];
                        flippedImageData.data[dstIndex + 3] = imageData.data[srcIndex + 3];
                    }
                }
        
                tempCtx.putImageData(flippedImageData, 0, 0);
        
                const finalCanvas = document.createElement('canvas');
                finalCanvas.width = width;
                finalCanvas.height = height;
                const finalCtx = finalCanvas.getContext('2d');
                if (!finalCtx) {
                    reject(new Error("Failed to create final canvas context"));
                    return;
                }
        
                finalCtx.beginPath();
                finalCtx.arc(width / 2, height / 2, Math.min(width, height) / 2, 0, Math.PI * 2);
                finalCtx.clip();
                finalCtx.drawImage(tempCanvas, 0, 0);
        
                if (finalCanvas.toBlob) {
                    finalCanvas.toBlob(blob => {
                        if (blob) {
                            resolve(blob);
                        } else {
                            reject(new Error("Canvas to Blob conversion failed"));
                        }
                    }, 'image/png', 1);
                } else {
                    const dataURL = finalCanvas.toDataURL('image/png');
                    const byteCharacters = atob(dataURL.split(',')[1]);
                    const byteNumbers = new Array(byteCharacters.length);
                    for (let i = 0; i < byteCharacters.length; i++) {
                        byteNumbers[i] = byteCharacters.charCodeAt(i);
                    }
                    const byteArray = new Uint8Array(byteNumbers);
                    const blob = new Blob([byteArray], { type: 'image/png' });
                    resolve(blob);
                }
            }
            cameraNode.removeFromParent();
            cameraNode.destroy();
        });
    }
}